package com.spmsys.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.spmsys.util.DBCPDataSource;
import com.spmsys.util.Database;
import com.spmsys.util.ExceptionStackTrace;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;


/**
 * 数据库操作类
 */
public class DatabaseOperation {
    private final Database database;

    public DatabaseOperation() {
        this.database = new Database(DBCPDataSource.getDataSource("sys"), DBCPDataSource.getDataSource("spmsys"));
    }

    public DatabaseOperation(String owner, String createBy, String updateBy) {
        this.database = new Database(DBCPDataSource.getDataSource("sys"), DBCPDataSource.getDataSource("spmsys"), owner, createBy, updateBy);
    }

    /**
     * 新增记录方法
     *
     * @param tableName 表名
     * @param record    记录
     * @return 结果
     */
    public JSONObject create(String tableName, JSONObject record) {
        JSONObject result = new JSONObject();
        try {
            result.put("data", database.dbCreate(tableName, JSONObject.parseObject(JSONObject.toJSONString(record.toJavaObject(Class.forName("com.spmsys.entity.spmsys." + tableName.substring(0, 1).toUpperCase() + tableName.substring(1))), SerializerFeature.WriteMapNullValue))));
        } catch (Exception e) {
            result.put("errorCode", "DATABASE_OPERATION_FAILED");
            result.put("errorMessage", ExceptionStackTrace.getExceptionInformation(e, ExceptionStackTrace.length(e) - 1));
        }
        //返回数据
        return result;
    }

    /**
     * 批量新增记录方法
     *
     * @param tableName 表名
     * @param records   记录列表
     * @return 结果
     */
    public JSONObject batchCreate(String tableName, JSONArray records) {
        JSONObject result = new JSONObject();
        try {
            result.put("data", database.dbBatchCreate(tableName, JSONObject.parseArray(JSONObject.toJSONString(records.toJavaList(Class.forName("com.spmsys.entity.spmsys." + tableName.substring(0, 1).toUpperCase() + tableName.substring(1))), SerializerFeature.WriteMapNullValue))));
        } catch (Exception e) {
            result.put("errorCode", "DATABASE_OPERATION_FAILED");
            result.put("errorMessage", ExceptionStackTrace.getExceptionInformation(e, ExceptionStackTrace.length(e) - 1));
        }
        //返回数据
        return result;
    }

    /**
     * 删除记录方法
     *
     * @param tableName 表名
     * @param id        数据标识
     * @return 结果
     */
    public JSONObject delete(String tableName, String id) {
        JSONObject result = new JSONObject();
        try {
            result.put("data", database.dbDelete(tableName, id));
        } catch (Exception e) {
            result.put("errorCode", "DATABASE_OPERATION_FAILED");
            result.put("errorMessage", ExceptionStackTrace.getExceptionInformation(e, ExceptionStackTrace.length(e) - 1));
        }
        //返回数据
        return result;
    }

    /**
     * 批量删除记录方法
     *
     * @param tableName 表名
     * @param where     查询条件
     * @return 结果
     */
    public JSONObject batchDelete(String tableName, JSONArray where) {
        JSONObject result = new JSONObject();
        try {
            result.put("data", database.dbBatchDelete(tableName, where));
        } catch (Exception e) {
            result.put("errorCode", "DATABASE_OPERATION_FAILED");
            result.put("errorMessage", ExceptionStackTrace.getExceptionInformation(e, ExceptionStackTrace.length(e) - 1));
        }
        //返回数据
        return result;
    }

    /**
     * 更新记录方法
     *
     * @param tableName 表名
     * @param id        数据标识
     * @param record    记录
     * @return 结果
     */
    public JSONObject update(String tableName, String id, JSONObject record) {
        JSONObject result = new JSONObject();
        try {
            Class<?> clazz = Class.forName("com.spmsys.entity.spmsys." + tableName.substring(0, 1).toUpperCase() + tableName.substring(1));
            List<String> fieldsName = new ArrayList<>();
            for (Field field : clazz.getDeclaredFields()) {
                fieldsName.add(field.getName());
            }
            for (String key : record.keySet()) {
                if (!fieldsName.contains(key)) {
                    record.remove(key);
                }
            }
            record.toJavaObject(clazz);
            result.put("data", database.dbUpdate(tableName, id, record));
        } catch (Exception e) {
            result.put("errorCode", "DATABASE_OPERATION_FAILED");
            result.put("errorMessage", ExceptionStackTrace.getExceptionInformation(e, ExceptionStackTrace.length(e) - 1));
        }
        //返回数据
        return result;
    }

    /**
     * 批量更新记录方法
     *
     * @param tableName 表名
     * @param where     查询条件
     * @param record    记录
     * @return 结果
     */
    public JSONObject batchUpdate(String tableName, JSONArray where, JSONObject record) {
        JSONObject result = new JSONObject();
        try {
            Class<?> clazz = Class.forName("com.spmsys.entity.spmsys." + tableName.substring(0, 1).toUpperCase() + tableName.substring(1));
            List<String> fieldsName = new ArrayList<>();
            for (Field field : clazz.getDeclaredFields()) {
                fieldsName.add(field.getName());
            }
            for (String key : record.keySet()) {
                if (!fieldsName.contains(key)) {
                    record.remove(key);
                }
            }
            record.toJavaObject(clazz);
            result.put("data", database.dbBatchUpdate(tableName, where, record));
        } catch (Exception e) {
            result.put("errorCode", "DATABASE_OPERATION_FAILED");
            result.put("errorMessage", ExceptionStackTrace.getExceptionInformation(e, ExceptionStackTrace.length(e) - 1));
        }
        //返回数据
        return result;
    }

    /**
     * 查询记录方法
     *
     * @param tableName 表名
     * @param id        数据标识
     * @return 结果
     */
    public JSONObject getItem(String tableName, String id) {
        JSONObject result = new JSONObject();
        try {
            result.put("data", database.dbGetItem(tableName, id));
        } catch (Exception e) {
            result.put("errorCode", "DATABASE_OPERATION_FAILED");
            result.put("errorMessage", ExceptionStackTrace.getExceptionInformation(e, ExceptionStackTrace.length(e) - 1));
        }
        //返回数据
        return result;
    }

    /**
     * 查询记录列表方法
     *
     * @param tableName 表名
     * @param pageNo    页码
     * @param pageSize  每页大小
     * @param orderBy   排序字段
     * @param orderType 排序方式
     * @param where     查询条件
     * @return 结果
     */
    public JSONObject getRecords(String tableName, Integer pageNo, Integer pageSize, String orderBy, String orderType, JSONArray where) {
        JSONObject result = new JSONObject();
        try {
            result.put("data", database.dbGetRecords(tableName, pageNo, pageSize, orderBy, orderType, where));
        } catch (Exception e) {
            result.put("errorCode", "DATABASE_OPERATION_FAILED");
            result.put("errorMessage", ExceptionStackTrace.getExceptionInformation(e, ExceptionStackTrace.length(e) - 1));
        }
        //返回数据
        return result;
    }
}
